//      core.cpp
//

#include "core.h"


Core::Core(QVector<qreal> &prodactionCosts, QVector<qreal> &storageExpenses)
{
    this->prodactionCosts = prodactionCosts;
    this->storageExpenses = storageExpenses;
}

void Core::preCalculate()
{
    for (quint32 i = 0; i < 4; i++)
    {
        W3[i] = storageExpenses[1] + prodactionCosts[3 - i];
    }
    MASS[0][2] = -1;
    MASS[0][3] = -1;
    MASS[1][3] = -1;
    for (quint32 i = 0; i < 3; i++)
    {
        for (quint32 j = 0; j < 4; j++)
        {
            if (MASS[i][j] != -1)
            {
                MASS[i][j] = W3[j] + storageExpenses[j] + prodactionCosts[4 - i + j];
            }
        }
    }
    for (quint32 i = 0; i < 3; i++)
    {
        qreal MIN2 = MASS[i][0];
        quint32 MINIMUM = 0;
        for(quint32 j = 0; j < 4; j++)
        {
            if((MASS[i][j] < MIN2) && (MASS[i][j] != -1))
            {
                MIN2 = MASS[i][j];
                MINIMUM = j;
            }
        }
        W2[i] = MIN2;
        S2[i] = MINIMUM;
        U2[i] = 4 - i + MINIMUM;
    }
   
    quint32 MINIMUM1 = 0;
    for (quint32 i = 0; i < 3; i++)
    {
        MASS1[i] = W2[i] + storageExpenses[i] + prodactionCosts[3 + i];
    }
    qreal MIN1 = MASS1[0];
    for (quint32 i = 0; i < 3; i++)
    {
			if (MASS1[i] < MIN1)
        {
            MIN1 = MASS1[i];
            MINIMUM1 = i;
        }
		}
    W1 = MIN1;
    S1 = MINIMUM1;
    U1 = 3 + MINIMUM1;

    qreal mini = W2[0];
    for (quint32 i = 0; i < 3; i++)
    {
        if (W2[i] <= mini)
        {
            mini = W2[i];
            num = i;
        }
    }
}

QVector<quint16> Core::calculate()
{
    preCalculate();
    QVector<quint16> order;
    order << 0;
    if (S1 == 0)
    {
        order << 1;
    }
    if (S1 == 1)
    {
        order << 2;
    }
    if (S1 == 2)
    {
        order << 3;
    }
    if (S2[num] == 0)
    {
        order << 4;
    }
    if (S2[num] == 1)
    {
        order << 5;
    }
    if (S2[num] == 2)
    {
        order << 6;
    }
    if (S2[num] == 3)
    {
        order << 7;
    }
    order << 8;
    lastSaveProd = order[2];
    return order;
}

void Core::getSecondStepValues(QVector<qreal>* mass,
                                                            QVector<qreal>* w2,
                                                            QVector<quint32>* s2,
                                                            QVector<quint32>* u2)
{
    mass->append(MASS[0][0]);
    mass->append(MASS[0][1]);
    mass->append(MASS[1][0]);
    mass->append(MASS[1][1]);
    mass->append(MASS[1][2]);
    mass->append(MASS[2][0]);
    mass->append(MASS[2][1]);
    mass->append(MASS[2][2]);
    mass->append(MASS[2][3]);
    w2->append(W2[0]);
    w2->append(W2[1]);
    w2->append(W2[2]);
    s2->append(S2[0]);
    s2->append(S2[1]);
    s2->append(S2[2]);
    u2->append(U2[0]);
    u2->append(U2[1]);
    u2->append(U2[2]);

}

QVector<qreal> Core::getLastStepValues()
{
    QVector<qreal> res;
    res << W3[0] << W3[1] << W3[2] << W3[3];
    return res;
}

void Core::getFirstStepValues(QVector<qreal>* mass,
                                                qreal* w1,
                                                quint32* s1,
                                                quint32* u1)
{
    mass->append(MASS1[0]);
    mass->append(MASS1[1]);
    mass->append(MASS1[2]);
    *w1 = W1;
    *s1 = S1;
    *u1 = U1;
}

QVector<quint32> Core::getProdactLine() const {
	QVector<quint32> res;
	res << U1;
	res << U2[S1];
	res << 7 - lastSaveProd;
	return res;
}

qreal Core::getTotalExpenses() const {
	return W1;
}
